/**********************************************************************
 * SailmiPIM - modular cross-platform feature Personal Information Manager Tools.
 * Copyright(C) 2006-2014  Georg Rudoy
 *
 * Distributed under the Boost Software License, Version 1.0.
 *(See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
 **********************************************************************/

#include "sysinfo.h"
#if !defined(Q_OS_WIN32)
#include <sys/utsname.h>
#endif
#include <array>
#include <QProcess>
#include <QTextStream>
#include <QFile>
#include <QSettings>

namespace SailmiPIM::Util::SysInfo
{
	QString GetOSName()
	{
		const auto& info = GetOSInfo();
		return info.Name_ + ' ' + info.Version_;
	}

	namespace Linux
	{
		QString GetLSBName()
		{
			QProcess proc;

			proc.start(QStringLiteral("/bin/sh"),
						QStringList { "-c", "lsb_release -ds" },
						QIODevice::ReadOnly);
			if(proc.waitForStarted())
			{
				QTextStream stream(&proc);
				QString ret;
				while(proc.waitForReadyRead())
					ret += stream.readAll();
				proc.close();
				if(!ret.isEmpty())
					return ret.remove('"').trimmed();
			}

			return {};
		}

		QString GetEtcOsName()
		{
			static const auto osReleaseFile = QStringLiteral("/etc/os-release");
			if(!QFile::exists(osReleaseFile))
				return {};

			QSettings relFile { osReleaseFile, QSettings::IniFormat };
            //relFile.setIniCodec("UTF-8");

			const auto& prettyName = relFile.value(QStringLiteral("PRETTY_NAME")).toString();
			const auto& name = relFile.value(QStringLiteral("NAME")).toString();
			const auto& version = relFile.value(QStringLiteral("VERSION")).toString();
			return !prettyName.isEmpty() ? prettyName :(name + " " + version);
		}

		QString GetEtcName()
		{
			struct OsInfo
			{
				QString path;
				QString name;
			};
			static const auto osptr = std::to_array<OsInfo>({
					{ QStringLiteral("/etc/mandrake-release"), QStringLiteral("Mandrake Linux") },
					{ QStringLiteral("/etc/debian_version"), QStringLiteral("Debian GNU/Linux") },
					{ QStringLiteral("/etc/gentoo-release"), QStringLiteral("Gentoo Linux") },
					{ QStringLiteral("/etc/exherbo-release"), QStringLiteral("Exherbo") },
					{ QStringLiteral("/etc/arch-release"), QStringLiteral("Arch Linux") },
					{ QStringLiteral("/etc/slackware-version"), QStringLiteral("Slackware Linux") },
					{ QStringLiteral("/etc/pld-release"), {} },
					{ QStringLiteral("/etc/lfs-release"), QStringLiteral("LFS") },
					{ QStringLiteral("/etc/SuSE-release"), QStringLiteral("SuSE linux") },
					{ QStringLiteral("/etc/conectiva-release"), QStringLiteral("Connectiva") },
					{ QStringLiteral("/etc/.installed"), {} },
					{ QStringLiteral("/etc/redhat-release"), {} },
				});
			for(const auto& os : osptr)
			{
				QFile f(os.path);
				if(f.open(QIODevice::ReadOnly))
				{
					QString data = QString(f.read(1024)).trimmed();
					return os.name.isEmpty() ?
							data :
							QStringLiteral("%1(%2)").arg(os.name, data);
				}
			}

			return {};
		}
	}

	namespace
	{
#ifndef Q_OS_MAC
		void Normalize(QString& osName)
		{
			auto trimQuotes = [&osName]
			{
				if(osName.startsWith('"') && osName.endsWith('"'))
					osName = osName.mid(1, osName.size() - 1);
			};

			trimQuotes();

			static const auto nameMarker = QStringLiteral("NAME=");
			if(osName.startsWith(nameMarker))
				osName = osName.mid(nameMarker.size());

			trimQuotes();
		}
#endif
	}

	OSInfo GetOSInfo()
	{
        return { .Arch_ = QSysInfo::buildCpuArchitecture(), .Name_ = QSysInfo::prettyProductName(), .Version_ = QSysInfo::productVersion(), .Flavour_ = {} };
	}
}
